#include "sms.h"

#define MAIN_LAYOUT_CONFIG_FILE "/usr/share/sms/main_layout/layout.xml"
#define MAIN_LAYOUT_MAX_DRAPE 16
#define MAIN_LAYOUT_NAME "layout-main"

#define ANIMATE_STOP     1
#define ANIMATE_RESTART  2
#define ANIMATE_CONTINUE 3


typedef enum _MAIN_ICON_TYPE{
	MAIN_ICON_TYPE_NONE,
	MAIN_ICON_TYPE_SHOW_SUB,
	MAIN_ICON_TYPE_EXEC,
	MAIN_ICON_TYPE_LAYOUT
}MAIN_ICON_TYPE;

typedef struct _Icon
{
	char *name;
	MAIN_ICON_TYPE type;

	GooCanvasItem *icon;
	GooCanvasItem *icon_a;

	LAYOUT_WIN_ID id;
	char *layout_property[2];

	char *cmd;
	char **argv;
	int argc;

	int size;
	int asize;
	int sub_count;
	int sub_cur;
	int sicon_jump_id;

	gboolean is_sub;

	struct _Icon *sub_icons;
	struct _Icon *sicon_cur;
	struct _Icon *sicon_jump;

	struct _Icon *next;
	struct _Icon *prv;

}Icon;

typedef struct _Title{	
	int x;
	int y;
	int size;
	char *color;
	char *font;
	GooCanvasItem *text;
}Title;

typedef struct _MainLayout
{
	GooCanvasItem *bg;
	GooCanvasItem *drape[MAIN_LAYOUT_MAX_DRAPE];

	gboolean in_sub;

	int micon_count;

	Icon *icons;
	Icon *micon_cur;
	Icon *micon_jump;

	Animate *animates;
	int animate_count;

	int micon_jump_id;

	int *micon_pos[2];
	int *sicon_pos[2];
	Exec *exec;
	Title title;
}MainLayout;

char *xml_path;

///////////////////////////////////
static void icon_ani_end(GooCanvasItem *item,gboolean stopped,gpointer user_data) ;


///////////////////////////////////



static void icon_get_exec_arg(const char *val,Icon *icon)
{
	//FIXME:
	return;
}

static void icon_get_layout_property(const char *val,Icon *icon)
{
	char *p=g_utf8_strchr(val,g_utf8_strlen(val,0),'|');
	if(!p)
		return ;
	icon->layout_property[0]=g_strndup(val,p-val);
	icon->layout_property[1]=g_strdup(val+1);	
}

static void main_layout_destroy_icon(Icon *icon)
{
	Icon *nicon,*picon;
	int i;

	if(!icon)
		return;

	nicon=icon->next;
	picon=icon->prv;
	if(nicon&&picon)
	{
		nicon->prv=picon;
		picon->next=nicon;
	}

	if(icon->name)
		free(icon->name);
	if(icon->icon)
		g_object_unref(icon->icon);
	if(icon->icon_a)
		g_object_unref(icon->icon_a);
	if(icon->layout_property[0])
		free(icon->layout_property[0]);
	if(icon->layout_property[1])
		free(icon->layout_property[1]);
	if(icon->cmd)
		free(icon->cmd);

	for(i=0;i<icon->argc;i++)
	{
		if(icon->argv[i])
			free(icon->argv[i]);
	}

	nicon=icon->sub_icons;
	for(i=0;i<icon->sub_count;i++)
	{	
		main_layout_destroy_icon(nicon);
		nicon=nicon->next;
	}

}

static void main_layout_create_pos(xmlNode *a_node,int count,int *pos[])
{
	int i,points;
	char key[16];
	xmlChar * val;

	points=sms_get_xml_int (a_node,(xmlChar*)"points",0);

	if(count<points)
		return ;

	*pos=(int *)g_malloc0(sizeof(int)*count+1);
	*(pos+1)=(int *)g_malloc0(sizeof(int)*count+1);

	for(i=0;i<count;i++)
	{
		sprintf(key,"p%d_x",i+1);
		pos[0][i] = sms_get_xml_int (a_node,(xmlChar*)key,0);
		sprintf(key,"p%d_y",i+1);
		pos[1][i] = sms_get_xml_int (a_node,(xmlChar*)key,0);
	}

	return;

err:
	if(pos)
		free(pos);
}

static Icon * main_layout_create_icon(xmlNode *a_node,Layout *layout)
{
	printf("~~~%s\n" ,__FUNCTION__);
	MainLayout *main_layout=layout->private;
	SMS *sms=layout->sms;

	int id;
	GdkPixbuf*  pixbuf;
	xmlChar * val;
	char pic[256];

	int d=0;

	Icon *icon=(Icon *)g_malloc0(sizeof(Icon)+1);
	if(!icon)
		goto err;

	val = xmlGetProp (a_node,(xmlChar*)"name");
	if(!val)
		goto err;
	icon->name=g_strdup(val);

	icon->size=sms_get_xml_int(a_node,(xmlChar*)"size",64);
	icon->asize=sms_get_xml_int(a_node,(xmlChar*)"asize",icon->size);

	//icon
	val = xmlGetProp (a_node,(xmlChar*)"pic");
	if(!val)
		goto err;
	sprintf(pic,"%s/%s/layout/%s/%s",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name,val);
	pixbuf=sms_load_pic(pic,icon->size,icon->size);
	if(!pixbuf)
		goto err;	
	icon->icon=goo_canvas_image_new (layout->cavas, pixbuf, 0, 0, NULL);	
	g_object_set(icon->icon,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	g_signal_connect(icon->icon,"animation-finished",(GCallback) icon_ani_end,layout);

	//icon ani
	val = xmlGetProp (a_node,(xmlChar*)"apic");
	if(!val)
		goto err;
	sprintf(pic,"%s/%s/layout/%s/%s",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name,val);
	pixbuf=sms_load_pic(pic,icon->asize,icon->asize);
	if(!pixbuf)
		goto err;
	icon->icon_a=goo_canvas_image_new (layout->cavas, pixbuf, 0, 0, NULL);
	g_object_set(icon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);

	//is layout ?
	val = xmlGetProp (a_node,(xmlChar*)"layout");
	if(val)
	{
		if (strcmp(val, "layout-video-list") == 0)
			xml_path = xmlGetProp (a_node,(xmlChar*)"layout_xml_path");

		id=sms_get_win_id(sms,val);
		if(id<0)
			goto err;
		icon->id=id;
		icon->type=MAIN_ICON_TYPE_LAYOUT;
		val = xmlGetProp (a_node,(xmlChar*)"layout_property");
		if(val)
		{
			icon_get_layout_property(val,icon);
		}
	}

	//is exec?
	if(icon->type==MAIN_ICON_TYPE_NONE)
	{
		val = xmlGetProp (a_node,(xmlChar*)"exec");
		if(val)
		{
			icon->type=MAIN_ICON_TYPE_EXEC;
			icon->cmd=g_strdup(val);
			printf("cmd=%s\n" ,icon->cmd);

			val = xmlGetProp (a_node,(xmlChar*)"exec_arg");
			if(val)
			{
				icon_get_exec_arg(val,icon);
			}
		}
	}

	//is father?
	if(icon->type==MAIN_ICON_TYPE_NONE)
	{
		xmlNode *cur_node=a_node->children;
		Icon *sub_icon;
		for (cur_node = cur_node; cur_node; cur_node = cur_node->next) {
			if (cur_node->type == XML_ELEMENT_NODE &&
					strcmp(cur_node->name,"icon")==0 )
			{
				sub_icon=main_layout_create_icon(cur_node,layout);
				if(sub_icon)
				{
					icon->type=MAIN_ICON_TYPE_SHOW_SUB;
					icon->sub_count++;
					if(icon->sub_icons)
					{
						Icon *picon;
						picon=icon->sub_icons->prv;
						picon->next=sub_icon;
						sub_icon->prv=picon;
						icon->sub_icons->prv=sub_icon;
						sub_icon->next=icon->sub_icons;
					}
					else
					{
						icon->sub_icons=sub_icon;
						sub_icon->next=sub_icon;
						sub_icon->prv=sub_icon;
					}
				}
			}
		}
	}

	return icon;
err:
	fprintf(stderr,"%s:error\n",__FUNCTION__);
	if(icon)
		main_layout_destroy_icon(icon);
	return NULL;
}

static gboolean main_layout_load_icons(xmlNode *a_node,Layout *layout)
{
	MainLayout *main_layout=layout->private;

	xmlNode *cur_node = NULL;
	Icon * icon;

	if(!a_node)
		return FALSE;
	for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
		if (cur_node->type == XML_ELEMENT_NODE) {
			if(strcmp(cur_node->name,"icon")==0)
			{
				icon=main_layout_create_icon(cur_node,layout);
				if(icon)
				{
					main_layout->micon_count++;
					if(main_layout->icons)
					{
						Icon *picon;
						picon=main_layout->icons->prv;
						picon->next=icon;
						icon->prv=picon;
						main_layout->icons->prv=icon;
						icon->next=main_layout->icons;
					}
					else
					{
						main_layout->icons=icon;
						icon->next=icon;
						icon->prv=icon;
					}
				}
			}
		}
	}
	return TRUE;
}

static gboolean main_layout_load_title(xmlNode *a_node,Layout *layout)
{
	MainLayout *main_layout=layout->private;
	GooCanvasItem *text4;
	Title * title=&(main_layout->title);
	xmlNode *cur_node = a_node;
	xmlChar * val;
	char font[64];
	char pic[256];

	GooCanvasItem *logo;
	sprintf(pic ,"%s/%s/layout/%s/%s" ,SMS_RESOURCE_DIR ,"default" ,layout->name ,"logo.png");
	GdkPixbuf  *pixbuf_logo = gdk_pixbuf_new_from_file_at_size(pic ,120 ,138 ,NULL);
	logo = goo_canvas_image_new(layout->cavas ,pixbuf_logo ,0 ,0 ,NULL);
	goo_canvas_item_set_simple_transform(logo ,656 ,19 ,1 ,0);

	if(!a_node)
		goto err;

	title->x=sms_get_xml_int(cur_node,(xmlChar*)"x",0);
	title->y=sms_get_xml_int(cur_node,(xmlChar*)"y",0);
	title->size=sms_get_xml_int(cur_node,(xmlChar*)"size",10);

	val = xmlGetProp (cur_node,(xmlChar*)"color");
	if(val)
	{
		title->color=g_strdup(val);
	}
	val = xmlGetProp (cur_node,(xmlChar*)"font");
	if(val)
	{
		title->font=g_strdup(val);
	}
	
	//sprintf(font ,"Sans Bold %d",title->size);
	sprintf(font ,"%s %d",title->font ,title->size);
	title->text=goo_canvas_text_new(layout->cavas,"",
			title->x,title->y,-1,GTK_ANCHOR_CENTER,
			"font", font,NULL);
	if(title->color)
		g_object_set(title->text,"fill_color",title->color,NULL);

	text4 = goo_canvas_text_new(layout->cavas,"东信北邮家庭教育演示系统",
			600 ,444 ,-1 ,GTK_ANCHOR_CENTER ,
			"font"  ,"Sans red 20" ,NULL);
	g_object_set(text4,"fill_color","red",NULL);


	return TRUE;
err:
	return FALSE;
}

static gboolean main_layout_load_draps(xmlNode *a_node,Layout *layout)
{
	MainLayout *main_layout=layout->private;

	xmlNode *cur_node = NULL;
	GdkPixbuf*  pixbuf;
	char pic[256];
	int i=0;
	int x,y,w,h;
	xmlChar * val;

	if(!a_node)
		goto err;
	for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
		if (cur_node->type == XML_ELEMENT_NODE) {
			if(strcmp(cur_node->name,"drape")==0)
			{			

				x=sms_get_xml_int(cur_node,(xmlChar*)"x",0);
				y=sms_get_xml_int(cur_node,(xmlChar*)"y",0);
				w=sms_get_xml_int(cur_node,(xmlChar*)"w",0);
				h=sms_get_xml_int(cur_node,(xmlChar*)"h",0);

				val = xmlGetProp (cur_node,(xmlChar*)"pic");
				if(!val)
					continue;
				sprintf(pic,"%s/%s/layout/%s/%s",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name,val);
				pixbuf=sms_load_pic(pic,w,h);
				if(!pixbuf)
					continue;
				main_layout->drape[i]=goo_canvas_image_new (layout->cavas, pixbuf, x, y, NULL);

				if(++i>MAIN_LAYOUT_MAX_DRAPE)
					break;
			}
		}
	}

	return TRUE;
err:
	return FALSE;
}

static gboolean main_layout_load_bg(xmlNode *a_node,Layout *layout)
{
	MainLayout *main_layout=layout->private;
	GdkPixbuf*  pixbuf;
	xmlChar * val;
	char pic[256];

	if(main_layout->bg||!a_node)
		return FALSE;

	val = xmlGetProp (a_node,(xmlChar*)"pic");
	if(!val)
		return FALSE;
	sprintf(pic,"%s/%s/layout/%s/%s",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name,val);

	pixbuf=sms_load_pic(pic,800,480);
	if(!pixbuf)
		return FALSE;

	main_layout->bg=goo_canvas_image_new (layout->cavas, pixbuf, 0, 0,NULL);	

	GooCanvasItem *wave ,*seaweed1 ,*seaweed2 ,*seaweed3 ,*ship;
	GdkPixbuf *pixbuf_ship = gdk_pixbuf_new_from_file("/usr/share/sms/default/layout/layout-main/Ship.png" ,NULL);
	ship = goo_canvas_image_new(layout->cavas ,pixbuf_ship ,0 ,0 ,NULL);
	goo_canvas_item_set_simple_transform(ship ,174 ,0 ,1 ,0);

	//animate_new (layout->cavas, "/usr/share/sms/default/layout/layout-main/Wave0.png",
	//		     -100, 90, 800, 0, 1, 0, 1, 0, FALSE, 4000, 100, GOO_CANVAS_ANIMATE_RESTART);
	//goo_canvas_item_animate(ship ,50 ,0 ,1 ,0 ,FALSE ,5000 ,40 ,
	//		GOO_CANVAS_ANIMATE_BOUNCE);

	/*GdkPixbuf *pixbuf_wave = gdk_pixbuf_new_from_file("/usr/share/sms/default/layout/layout-main/Wave0.png" ,NULL);
	  wave = goo_canvas_image_new(layout->cavas ,pixbuf_wave ,0 ,0 ,NULL);
	//goo_canvas_item_translate(wave ,0 ,103);
	goo_canvas_item_set_simple_transform(wave ,-800 ,90 ,1 ,0);
	goo_canvas_item_animate(wave ,800 ,0 ,1 ,0 ,FALSE ,40000 ,100 ,
	GOO_CANVAS_ANIMATE_BOUNCE);*/

	/*GdkPixbuf *pixbuf_sea1 =gdk_pixbuf_new_from_file("/usr/share/sms/default/layout/layout-main/Seaweed1.png" ,NULL);
	  seaweed1 = goo_canvas_image_new(layout->cavas ,pixbuf_sea1 ,0 ,0 ,NULL);
	  goo_canvas_item_set_simple_transform(seaweed1 ,117 ,400 ,1 ,0);
	  goo_canvas_item_animate(seaweed1 ,167 ,360 ,2 ,0 ,TRUE ,10000 ,120 ,
	  GOO_CANVAS_ANIMATE_BOUNCE);
	  GdkPixbuf *pixbuf_sea2 =gdk_pixbuf_new_from_file("/usr/share/sms/default/layout/layout-main/Seaweed.png" ,NULL);
	  seaweed2 = goo_canvas_image_new(layout->cavas ,pixbuf_sea2 ,0 ,0 ,NULL);
	  goo_canvas_item_set_simple_transform(seaweed2 ,464 ,451 ,1 ,0);
	  goo_canvas_item_animate(seaweed2 ,400 ,390 ,2 ,0 ,TRUE ,10000 ,120 ,
	  GOO_CANVAS_ANIMATE_BOUNCE);

	  GdkPixbuf *pixbuf_sea3 =gdk_pixbuf_new_from_file("/usr/share/sms/default/layout/layout-main/Seaweed1.png" ,NULL);
	  seaweed3 = goo_canvas_image_new(layout->cavas ,pixbuf_sea3 ,0 ,0 ,NULL);
	  goo_canvas_item_set_simple_transform(seaweed3 ,640 ,449 ,1 ,0);
	  goo_canvas_item_animate(seaweed3 ,640 ,380 ,2 ,0 ,TRUE ,10000 ,120 ,
	  GOO_CANVAS_ANIMATE_BOUNCE);*/
	//g_object_unref(pixbuf_sea1);
	//g_object_unref(pixbuf_sea2);
	//g_object_unref(pixbuf_sea3);
	return TRUE;
}


/*
 *hjq add for stop animate
 */

void mainlayout_animation_finished (GooCanvasItem *item, gboolean stopped, gpointer user_data)
{
	printf("~~~%s\n" ,__FUNCTION__);
	MainLayout *layout = (MainLayout*) user_data;
	if (stopped)
	{
		g_print("manually stop.\n");
	}
	else
	{
		g_print("auto stop.\n");
		//goo_canvas_item_set_simple_transform(item , -100 ,90 ,1 ,0);
		//goo_canvas_item_animate(item, 0, 90, 1, 0, TRUE, 4000, 100, GOO_CANVAS_ANIMATE_RESET);
		mainlayout_animate_control (layout, ANIMATE_RESTART);
	}
}

gboolean mainlayout_timeout_callback(gpointer user_data)
{
	printf("~~~%s\n" ,__FUNCTION__);
	MainLayout *layout = (MainLayout*) user_data;
	mainlayout_animate_control (layout, ANIMATE_CONTINUE);
	return FALSE;
}

/*
 * 1: stop
 * 2: restart
 * 3: continue
 * */

void mainlayout_animate_control (MainLayout *layout, int control)
{
	printf("~~~%s\n" ,__FUNCTION__);
	int i;
	Animate *animate;
	for (i=0; i<layout->animate_count; i++)
	{
		animate = layout->animates;
		switch (control)
		{
			case ANIMATE_STOP:
				animate_stop(animate);
				break;
			case ANIMATE_RESTART:
				animate_restart(animate);
				break;
			case ANIMATE_CONTINUE:
				animate_continue (animate);
				break;
			default:
				break;
		}
		animate = animate->next;
	}
}

#define ANIMATE_FREEZE   1
#define ANIMATE_RESET    2
#define ANIMATE_RESTART  3
#define ANIMATE_BOUNCE   4

static Animate * main_layout_create_animate(xmlNode *a_node,Layout *layout)
{
	printf("~~~%s\n" ,__FUNCTION__);

	MainLayout *main_layout=layout->private;
	Animate *animate;
	xmlChar * val;
	char pic[256];

	gdouble start_x;
	gdouble start_y;
	gdouble stop_x;
	gdouble stop_y;

	gdouble init_scale;
	gdouble init_rotation;
	gdouble animate_scale;
	gdouble animate_rotation;
	gboolean isAbsolute;
	gint total_time;
	gint step_time;
	GooCanvasAnimateType type;

	start_x = sms_get_xml_double (a_node, (xmlChar*)"start_x", 0);
	start_y = sms_get_xml_double (a_node, (xmlChar*)"start_y", 0);
	stop_x = sms_get_xml_double (a_node, (xmlChar*)"stop_x", 0);
	stop_y = sms_get_xml_double (a_node, (xmlChar*)"stop_y", 0);
	init_scale = sms_get_xml_double (a_node, (xmlChar*)"init_scale", 0);
	init_rotation = sms_get_xml_double (a_node, (xmlChar*)"init_rotation", 0);
	animate_scale = sms_get_xml_double (a_node, (xmlChar*)"animate_scale", 0);
	animate_rotation = sms_get_xml_double (a_node, (xmlChar*)"animate_rotation", 0);
	isAbsolute = sms_get_xml_boolean (a_node, (xmlChar*)"isAbsolute");
	total_time = sms_get_xml_int (a_node, (xmlChar*)"total_time", 0);
	step_time = sms_get_xml_int (a_node, (xmlChar*)"step_time", 0);

	switch (sms_get_xml_int (a_node, (xmlChar*)"type", 1))
	{
		case ANIMATE_FREEZE:
			type = GOO_CANVAS_ANIMATE_FREEZE;
			break;
		case ANIMATE_RESET:
			type = GOO_CANVAS_ANIMATE_RESET;
			break;
		case ANIMATE_RESTART:
			type = GOO_CANVAS_ANIMATE_RESTART;
			break;
		case ANIMATE_BOUNCE:
			type = GOO_CANVAS_ANIMATE_BOUNCE;
			break;
		default: break;
	}
	g_print ("startx: %f, starty: %f, stopx: %f, stopy: %f,init_scale: %f, animate_scale: %f, animate_rotation: %f, total_time: %d, step_time %d\n",
			start_x, start_y, stop_x, stop_y, init_scale, animate_scale, total_time, step_time);

	val = xmlGetProp (a_node,(xmlChar*)"pic");
	if(!val)
		goto err;
	sprintf(pic,"%s/%s/layout/%s/%s",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name,val);
	g_print ("pic path: %s", pic);

	animate = animate_new (layout->cavas, pic, start_x, start_y, stop_x, stop_y, init_scale, init_rotation,
			animate_scale, animate_rotation, isAbsolute, total_time, step_time, type);
	g_signal_connect (G_OBJECT (animate->cavas), "animation-finished", G_CALLBACK (mainlayout_animation_finished), main_layout);
	return animate;
err:
	fprintf(stderr,"%s:error\n",__FUNCTION__);
	return NULL;
}

static gboolean main_layout_load_animates(xmlNode *a_node, Layout *layout)
{
	MainLayout *main_layout=layout->private;

	xmlNode *cur_node = NULL;
	Animate * animate;

	if(!a_node)
		return FALSE;
	for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
		if (cur_node->type == XML_ELEMENT_NODE) {
			if(strcmp(cur_node->name,"animate")==0)
			{
				animate = main_layout_create_animate(cur_node, layout);
				if(animate)
				{
					main_layout->animate_count++;
					if(main_layout->animates)
					{
						main_layout->animates->next = animate;
					}
					else
					{
						main_layout->animates = animate;
					}
				}
			}
		}
	}
	return TRUE;
}

static gboolean main_layout_travel_xml(xmlNode *a_node,Layout *layout)
{
	MainLayout *main_layout=layout->private;

	xmlNode *cur_node = NULL;
	xmlNode *bg_node = NULL;
	xmlNode *icon_node = NULL;
	xmlNode *title_node = NULL;
	xmlNode *drape_node = NULL;
	xmlNode *animate_node = NULL;

	for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
		if (cur_node->type == XML_ELEMENT_NODE) {
			printf("node type: Element, name: %s\n", cur_node->name);
			if(strcmp(cur_node->name,"bg")==0)
				bg_node=cur_node;
			else if(strcmp(cur_node->name,"icons")==0)
				icon_node=cur_node;
			else if(strcmp(cur_node->name,"title")==0)
				title_node=cur_node;
			else if(strcmp(cur_node->name,"draps")==0)
				drape_node=cur_node;
			else if(strcmp(cur_node->name,"micon_pos")==0)
				main_layout_create_pos(cur_node,5,main_layout->micon_pos);
			else if(strcmp(cur_node->name,"sicon_pos")==0)
				main_layout_create_pos(cur_node,3,main_layout->sicon_pos);
			else if(strcmp(cur_node->name,"animates")==0)
				animate_node = cur_node;
		}
	}
	if(!bg_node||!icon_node||!title_node||!drape_node||!animate_node)
		return FALSE;


	main_layout_load_bg(bg_node,layout);
	main_layout_load_animates (animate_node->children, layout);
	main_layout_load_icons(icon_node->children,layout);
	main_layout_load_title(title_node,layout);

	//main_layout_load_draps(drape_node->children,layout);

	if(main_layout->micon_count>=5&&main_layout->micon_pos&&main_layout->sicon_pos)
		return TRUE;

	return FALSE;
}

#define MAIN_LAYOUT_ANI_DURATION 300
#define MAIN_LAYOUT_ANI_STEP	50

static void icon_ani_end(GooCanvasItem *item,gboolean stopped,gpointer user_data) 
{
	printf("~~~~%s\n" ,__FUNCTION__);
	double x,y,s,r;
	Layout *layout=user_data;
	MainLayout *main_layout=layout->private;
	int **mpos=main_layout->micon_pos;
	int **spos=main_layout->sicon_pos;
	int p=main_layout->micon_cur->size;

	SMS *sms = layout->sms ;

	if(!main_layout->in_sub)
	{
		gboolean is_sub=(gboolean)g_object_get_data(G_OBJECT(item),"is-sub");
		if(is_sub)
			g_object_set(item,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	}

	if(item==main_layout->micon_cur->icon)
	{
		int sp=(main_layout->micon_cur->size-main_layout->micon_cur->size)/2;
		g_object_set(main_layout->micon_cur->icon_a,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
		g_object_set(main_layout->micon_cur->icon,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);

		goo_canvas_item_set_simple_transform(main_layout->micon_cur->icon_a,mpos[0][0]-sp,mpos[1][0]-sp,1,0);

		g_object_set(main_layout->title.text,"text",main_layout->micon_cur->name,NULL);
		sms->busy = FALSE ;

		return ;		
	}

	if(main_layout->micon_jump && item==main_layout->micon_jump->icon)
	{
		GooCanvasItem *jitem;
		int id=main_layout->micon_jump_id;
		int xx;
		if(id==2)
		{
			xx=mpos[0][id]+p;
			jitem=main_layout->micon_cur->next->next->icon;
		}
		else
		{
			xx=mpos[0][id];
			jitem=main_layout->micon_cur->prv->prv->icon;
		}
		g_object_set(item,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
		g_object_set(jitem,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
		goo_canvas_item_set_simple_transform(jitem,xx,mpos[1][id]+p,0.1,0);
		goo_canvas_item_animate(jitem,mpos[0][id],mpos[1][id],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,
				GOO_CANVAS_ANIMATE_FREEZE);
		main_layout->micon_jump=NULL;
		return;
	}

	if(main_layout->micon_cur->sicon_cur&&
			item==main_layout->micon_cur->sicon_cur->icon)
	{
		Icon *sicon=main_layout->micon_cur->sicon_cur;
		if(main_layout->in_sub)
		{			
			int sp=(main_layout->micon_cur->size-main_layout->micon_cur->size)/2;
			goo_canvas_item_set_simple_transform(sicon->icon_a,spos[0][0]-sp,spos[1][0]-sp,1,0);
			g_object_set(sicon->icon_a,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
			g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);

			g_object_set(main_layout->title.text,"text",sicon->name,NULL);

		}
		else
		{
			g_object_set(main_layout->title.text,"text",main_layout->micon_cur->name,NULL);
		}
		return ;
	}

	if( main_layout->micon_cur->sicon_jump &&
			item==main_layout->micon_cur->sicon_jump->icon)
	{
		int sp=(main_layout->micon_cur->size-main_layout->micon_cur->size);
		int id=main_layout->micon_cur->sicon_jump_id;
		int xx;
		if(id==1)
			xx=spos[0][0]+main_layout->micon_cur->sicon_jump->size;
		else
			xx=spos[0][0];

		goo_canvas_item_set_simple_transform(item,xx,spos[1][id]+p/2,0.1,0);
		goo_canvas_item_animate(item,spos[0][id],spos[1][id],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,
				GOO_CANVAS_ANIMATE_FREEZE);

		main_layout->micon_cur->sicon_jump=NULL;
		return ;
	}
}

static void main_layout_move_micon(Layout *layout,gboolean is_left)
{
	printf("~~~~%s\n" ,__FUNCTION__);
	MainLayout *main_layout=layout->private;
	Icon *icon;
	int **mpos=main_layout->micon_pos;
	int p=main_layout->micon_cur->size;
	icon=main_layout->micon_cur;

	g_object_set(icon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	g_object_set(icon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	if(is_left)
	{		
		goo_canvas_item_animate(icon->icon,mpos[0][1],mpos[1][1],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}
	else
	{
		goo_canvas_item_animate(icon->icon,mpos[0][3],mpos[1][3],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}

	icon=icon->next;	
	if(is_left)
	{		
		goo_canvas_item_animate(icon->icon,mpos[0][2],mpos[1][2],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}
	else
	{
		goo_canvas_item_animate(icon->icon,mpos[0][0],mpos[1][0],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		//set end animate
	}

	icon=icon->next;	
	if(is_left)
	{		
		goo_canvas_item_animate(icon->icon,mpos[0][2]+p,mpos[1][2]+p,0.1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		//set end animate
		main_layout->micon_jump=icon;
		main_layout->micon_jump_id=4;
	}
	else
	{
		goo_canvas_item_animate(icon->icon,mpos[0][1],mpos[1][1],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}

	icon=main_layout->micon_cur->prv;	
	if(is_left)
	{		
		goo_canvas_item_animate(icon->icon,mpos[0][0],mpos[1][0],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		//set end animate
	}
	else
	{
		goo_canvas_item_animate(icon->icon,mpos[0][4],mpos[1][4],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}

	icon=icon->prv;	
	if(is_left)
	{		
		goo_canvas_item_animate(icon->icon,mpos[0][3],mpos[1][3],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}
	else
	{
		goo_canvas_item_animate(icon->icon,mpos[0][4],mpos[1][4]+p,0.1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		main_layout->micon_jump=icon;
		main_layout->micon_jump_id=2;
	}

	if(is_left)
		main_layout->micon_cur=main_layout->micon_cur->prv;
	else
		main_layout->micon_cur=main_layout->micon_cur->next;

}

static void main_layout_move_sicon(Layout *layout,gboolean is_left)
{
	MainLayout *main_layout=layout->private;
	Icon *icon=main_layout->micon_cur;
	Icon *sicon=icon->sicon_cur;
	int **spos=main_layout->sicon_pos;
	int **mpos=main_layout->micon_pos;
	int p=main_layout->micon_cur->size/2;

	if(!sicon)
		return;
	if(sicon==sicon->next)
		return;


	if(sicon->next==sicon->prv)
	{
		if(sicon==icon->sub_icons&&!is_left)
		{
			g_object_set(sicon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
			g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
			goo_canvas_item_animate(sicon->icon,spos[0][2],spos[1][2],1,0,TRUE,
					MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
			goo_canvas_item_animate(sicon->next->icon,spos[0][0],spos[1][0],1,0,TRUE,
					MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
			icon->sicon_cur=sicon->next;
		}
		else if(sicon!=icon->sub_icons&&is_left)
		{
			g_object_set(sicon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
			g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
			goo_canvas_item_animate(sicon->icon,spos[0][1],spos[1][1],1,0,TRUE,
					MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
			goo_canvas_item_animate(sicon->next->icon,spos[0][0],spos[1][0],1,0,TRUE,
					MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
			icon->sicon_cur=sicon->next;
		}

		return ;
	}

	//more then 3 icons.
	g_object_set(sicon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);

	if(is_left)
	{
		goo_canvas_item_animate(sicon->icon,spos[0][1],spos[1][1],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}
	else
	{
		goo_canvas_item_animate(sicon->icon,spos[0][2],spos[1][2],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}

	sicon=sicon->next;
	if(is_left)
	{
		goo_canvas_item_animate(sicon->icon,spos[0][0]+sicon->size,spos[1][1]+p,0.1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		icon->sicon_jump=sicon;
		icon->sicon_jump_id=2;
	}
	else
	{
		goo_canvas_item_animate(sicon->icon,spos[0][0],spos[1][0],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}

	sicon=sicon->prv->prv;
	if(is_left)
	{
		goo_canvas_item_animate(sicon->icon,spos[0][0],spos[1][0],1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	}
	else
	{
		goo_canvas_item_animate(sicon->icon,spos[0][0],spos[1][2]+p,0.1,0,TRUE,
				MAIN_LAYOUT_ANI_DURATION/2,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
		icon->sicon_jump=sicon;
		icon->sicon_jump_id=1;
	}

	if(is_left)
		icon->sicon_cur=icon->sicon_cur->prv;
	else
		icon->sicon_cur=icon->sicon_cur->next;
}

static gboolean main_layout_show_sicon(Layout *layout)
{
	MainLayout *main_layout=layout->private;
	Icon *icon=main_layout->micon_cur;
	Icon *sicon=icon->sub_icons;
	int **spos=main_layout->sicon_pos;
	int **mpos=main_layout->micon_pos;

	if(!sicon)
		return FALSE;

	icon->sicon_cur=sicon;
	icon->sicon_jump=NULL;

	goo_canvas_item_set_simple_transform(sicon->icon,mpos[0][0]+32,
			mpos[1][0]+32,0.1,0);
	g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	goo_canvas_item_animate(sicon->icon,spos[0][0],spos[1][0],1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);
	//goo_canvas_item_lower(icon->icon_a,sicon->icon);

	if(sicon==sicon->next)
		return TRUE;
	sicon=sicon->next;

	goo_canvas_item_set_simple_transform(sicon->icon,mpos[0][0]+32,
			mpos[1][0]+32,0.1,0);
	g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	goo_canvas_item_animate(sicon->icon,spos[0][1],spos[1][1],1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);

	if(sicon->prv==sicon->next)
		return TRUE;
	sicon=sicon->next;

	goo_canvas_item_set_simple_transform(sicon->icon,mpos[0][0]+32,
			mpos[1][0]+32,0.1,0);
	g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	goo_canvas_item_animate(sicon->icon,spos[0][2],spos[1][2],1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);

	return TRUE;
}

static gboolean main_layout_hide_sicon(Layout *layout)
{
	MainLayout *main_layout=layout->private;
	Icon *icon=main_layout->micon_cur;
	Icon *sicon=icon->sicon_cur;
	int **spos=main_layout->sicon_pos;
	int **mpos=main_layout->micon_pos;

	if(!sicon)
		return FALSE;

	g_object_set(sicon->icon_a,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	g_object_set(sicon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	goo_canvas_item_animate(sicon->icon,mpos[0][0]+32,mpos[1][0]+32,0.1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);

	if(sicon==sicon->next)
		return TRUE;
	sicon=sicon->next;

	goo_canvas_item_animate(sicon->icon,mpos[0][0]+32,mpos[1][0]+32,0.1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);

	if(sicon->prv==sicon->next)
		return TRUE;
	sicon=sicon->next;

	goo_canvas_item_animate(sicon->icon,mpos[0][0]+32,mpos[1][0]+32,0.1,0,TRUE,
			MAIN_LAYOUT_ANI_DURATION,MAIN_LAYOUT_ANI_STEP,GOO_CANVAS_ANIMATE_FREEZE);


	return TRUE;
}

gboolean main_layout_load_config(Layout *layout)
{
	gboolean ret=FALSE;
	xmlDoc *doc = NULL;
	xmlNode *root_element = NULL;

	MainLayout *main_layout=layout->private;

	char conf[256];
	sprintf(conf,"%s/%s/layout/%s/layout.xml",SMS_RESOURCE_DIR,"default"/*theme*/,layout->name);

	doc = xmlReadFile(conf, NULL, 0);

	if (doc == NULL) {
		fprintf(stderr,"error: could not parse file %s\n", conf);
		return ret;
	}

	root_element = xmlDocGetRootElement(doc);

	if(root_element)
	{
		xmlNode *cur_node = NULL;
		for (cur_node = root_element; cur_node; cur_node = cur_node->next) {
			if (cur_node->type == XML_ELEMENT_NODE) {
				ret=TRUE;
				break;
			}
		}
		if(ret)
			ret=main_layout_travel_xml(cur_node->children,layout);
	}

	xmlFreeDoc(doc);
	xmlCleanupParser();
	return ret;
}

static void main_layout_reset_icon(Icon * icon,int x,int y,int **mpos)
{
	Icon *sicon=icon->sub_icons;

	goo_canvas_item_translate(icon->icon,x,y);
	g_object_set(icon->icon,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);

	if(!sicon)
		return;

	do{
		g_object_set_data(G_OBJECT(sicon->icon),"is-sub",(gpointer)TRUE);
		sicon=sicon->next;
	}while(sicon!=icon->sub_icons);
}

void main_layout_reset_icons(Layout *layout)
{
	printf("~~~%s\n" ,__FUNCTION__);
	MainLayout *main_layout=layout->private;
	Icon * icon=main_layout->icons;
	int **mpos=main_layout->micon_pos;

	main_layout_reset_icon(icon,mpos[0][0],mpos[1][0],mpos);
	goo_canvas_item_translate(icon->icon_a,mpos[0][0],mpos[1][0]);	
	g_object_set(icon->icon,"visibility",GOO_CANVAS_ITEM_HIDDEN,NULL);
	g_object_set(icon->icon_a,"visibility",GOO_CANVAS_ITEM_VISIBLE,NULL);
	g_object_set(main_layout->title.text,"text",icon->name,NULL);
	icon=icon->next;
	main_layout_reset_icon(icon,mpos[0][1],mpos[1][1],mpos);

	icon=icon->next;
	main_layout_reset_icon(icon,mpos[0][2],mpos[1][2],mpos);

	icon=main_layout->icons->prv;
	main_layout_reset_icon(icon,mpos[0][3],mpos[1][3],mpos);

	icon=icon->prv;
	main_layout_reset_icon(icon,mpos[0][4],mpos[1][4],mpos);

	main_layout->micon_cur=main_layout->icons;	
}

gboolean main_layout_init(Layout *layout,gpointer data)
{
	printf("call %s\n",__FUNCTION__);


	MainLayout *main_layout=(MainLayout *)g_malloc0(sizeof(MainLayout)+1);
	layout->private=(void *)main_layout;

	layout->cavas = goo_canvas_group_new(layout->parent,NULL);	//can auto free icon from parent


	if(!main_layout_load_config(layout))
	{
		fprintf(stderr,"%s:load config err\n",__FUNCTION__);
		return FALSE;//exit(-1);
	}

	main_layout_reset_icons(layout);
	return TRUE;
}

gboolean main_layout_clear(Layout *layout,gpointer data)
{

	return TRUE;
}
static gboolean main_layout_exec_finish(Exec *exec,gpointer data)
{
	printf("~~~%s\n" ,__FUNCTION__);
	MainLayout *main_layout=data;
	exec_destroy(main_layout->exec);
	main_layout->exec=NULL;
}

gboolean main_layout_key_press(Layout * layout,GdkEventKey *event)
{
	MainLayout *main_layout;

	main_layout=layout->private;
	SMS *sms = (SMS *)layout->sms;

	if(event->keyval==GDK_Left)
	{
		sms->busy = TRUE ;
		mainlayout_animate_control (main_layout, ANIMATE_STOP);
		g_timeout_add(300, (GSourceFunc) mainlayout_timeout_callback, main_layout);
		if(main_layout->in_sub)
		{
			main_layout_move_sicon(layout,TRUE);
		}
		else
		{
			main_layout_move_micon(layout,TRUE);
		}
		return TRUE;
	}
	else if(event->keyval==GDK_Right)
	{
		sms->busy = TRUE ;
		mainlayout_animate_control (main_layout, ANIMATE_STOP);
		g_timeout_add(300, (GSourceFunc) mainlayout_timeout_callback, main_layout);
		if(main_layout->in_sub)
		{
			main_layout_move_sicon(layout,FALSE);
		}
		else
		{
			main_layout_move_micon(layout,FALSE);
		}
		return TRUE;
	} else if (event->keyval==GDK_Up) {
		UpdateDeamon *deamon = update_deamon_new(layout->sms);
		update_deamon_timeout_update(deamon);
		return TRUE;
	}else if (event->keyval==97) {
		if (sms->items[LAYOUT_ITEM_PROMPTBAR]->visable) {
		   	layout_hide (sms->items[LAYOUT_ITEM_PROMPTBAR]);
		} else {
		   	layout_show (sms->items[LAYOUT_ITEM_PROMPTBAR]);
		}
	}
	/*
	   else if(event->keyval==GDK_Up)
	   {
	   if(!main_layout->in_sub)
	   {
	   main_layout->in_sub=main_layout_show_sicon(layout);
	   }
	   return TRUE;
	   }
	   else if(event->keyval==GDK_Down)
	   {
	   if(main_layout->in_sub)
	   {
	   main_layout->in_sub=!main_layout_hide_sicon(layout);
	   }
	   return TRUE;
	   }
	   */
	   else if(event->keyval==GDK_Return)
	   {
		   Icon *icon;
		   if(main_layout->in_sub)
			   icon=main_layout->micon_cur->sicon_cur;
		   else
			   icon=main_layout->micon_cur;
		   printf("icon->type=%d\n",icon->type);
		   printf("cmd=%s\n" ,icon->cmd);
		   //if(icon->type==MAIN_ICON_TYPE_SHOW_SUB)
		   //{
		   //main_layout->in_sub=main_layout_show_sicon(layout);
		   //}
		   if(icon->type==MAIN_ICON_TYPE_EXEC)
		   {
			   printf("exec=%s\n" ,icon->cmd);
			   system(icon->cmd);
			   //char *argv[]={"gedit" ,NULL};
			   //main_layout->exec=exec_create("gedit" ,2 ,argv ,FALSE ,main_layout_exec_finish,main_layout);


		   }
		   else if(icon->type==MAIN_ICON_TYPE_LAYOUT)
		   {			
			   if(icon->id == LAYOUT_WIN_VIDEO_LIST) {
				   sms_change_win_with_property(layout->sms, LAYOUT_WIN_VIDEO_LIST, "xml_path", xml_path);
				   return TRUE;
			   }
			   sms_change_win_to(layout->sms,icon->id);

			   //mainlayout_animate_control (layout, ANIMATE_STOP);
		   }
		   return TRUE;	
	   }

	   printf("%s : propagate the event\n",__FUNCTION__);
	   return FALSE;
}

Layout *main_layout_new(GooCanvasItem * parent,gpointer sms)
{
	Layout *layout=layout_new( parent,LAYOUT_TYPE_WIN,LAYOUT_WIN_MAIN,
			MAIN_LAYOUT_NAME,sms);

	layout_set_func(layout,"init",main_layout_init);
	layout_set_func(layout,"clear",main_layout_clear);
	layout_set_func(layout,"key-press",main_layout_key_press);

	return layout;
}
